<script setup>
import {ref, onUnmounted, watch, onMounted, inject} from 'vue';
import {streamChat} from '../apis/chat';
import {getMessages, deleteAllMessages, getMemoryId} from '../apis/messages';
import AiMessage from '../components/AiMessage.vue';

// 状态管理
const prompt = ref('');           // 用户输入内容
const messages = ref([]);         // 聊天消息列表
const loading = ref(false);       // 加载状态
const abortController = ref(null); // 用于取消请求
const message = ref({
  prompt: '',
  memoryId: localStorage.getItem('memoryId') || '',
})

// 本地存储, 判断会话是否存在
const memoryId = ref(localStorage.getItem('memoryId') || '');
const flg = ref(localStorage.getItem('flg') === 'true');

// 注入来自Layout的通信变量
const newChatRequested = inject('newChatRequested');
const selectedChatId = inject('selectedChatId');
const clearChatContent = inject('clearChatContent');

// 配置参数
const CONFIG = {
  REQUEST_TIMEOUT: 30000,       // 请求超时时间(毫秒)
  SCROLL_DELAY: 100,           // 滚动到底部的延迟时间(毫秒)
  DEBUG: false                  // 是否启用调试日志
};

// 监听新建对话请求
watch(newChatRequested, async () => {
  await resetChat();
});

// 监听选中的聊天ID变化
watch(selectedChatId, async (newChatId) => {
  if (newChatId) {
    // 如果选中了聊天，则加载该聊天的消息
    await loadChatMessages(newChatId);
  }
});

// 监听清除聊天内容的事件
watch(clearChatContent, async () => {
  // 清除当前显示的聊天内容
  messages.value = [];
  memoryId.value = '';
  message.value.memoryId = '';
  localStorage.removeItem('memoryId');
  localStorage.removeItem('flg');
  flg.value = false;
});

// 请求清理函数
onUnmounted(() => {
  if (abortController.value) {
    abortController.value.abort();
  }
});

/**
 * 发送消息并获取AI响应
 * 核心流程: 发送用户消息 -> 收集AI响应 -> 使用打字效果显示
 */
const sendMessage = async () => {
  if (!prompt.value.trim() || loading.value) return;

  // 确保使用当前会话的memoryId
  message.value.prompt = prompt.value.trim();
  message.value.memoryId = memoryId.value;

  prompt.value = ''; // 清空输入框

  // 获取当前时间
  const currentTime = new Date();

  // 先在界面上添加用户消息
  const userMessage = {
    id: `user_${Date.now()}`, // 临时ID，使用前缀确保唯一性
    content: message.value.prompt,
    role: 'user',
    createdAt: currentTime
  };
  messages.value.push(userMessage);

  // 添加AI占位消息
  const aiMessage = {
    id: `ai_${Date.now() + 1}`, // 临时ID，使用前缀确保唯一性
    content: '',
    role: 'ai',
    createdAt: new Date(currentTime.getTime() + 1) // 确保时间顺序正确
  };
  messages.value.push(aiMessage);

  // 强制滚动到底部
  scrollToBottom(true);

  loading.value = true;

  try {
    // 取消之前的请求
    if (abortController.value) {
      abortController.value.abort();
    }

    // 准备新的请求
    abortController.value = new AbortController();

    // 发送API请求并处理响应
    await processApiRequest(message.value, aiMessage);

  } catch (error) {
    console.error('请求过程发生异常:', error);
    handleRequestError('请求出错，请稍后再试', aiMessage);
  }
};

/**
 * 处理API请求并解析响应
 * @param message
 * @param {Object} aiMessage - AI消息对象
 */
const processApiRequest = async (message, aiMessage) => {
  // 用于收集完整响应
  let fullResponse = '';
  let requestCompleted = false;

  // 添加超时保护
  const timeoutId = setTimeout(() => {
    if (!requestCompleted && loading.value) {
      handleRequestTimeout(fullResponse, aiMessage);
    }
  }, CONFIG.REQUEST_TIMEOUT);

  // 处理请求完成的通用逻辑
  const completeRequest = () => {
    loading.value = false;
    requestCompleted = true;
    clearTimeout(timeoutId);
  };

  // 处理超时情况
  const handleRequestTimeout = (response, aiMessage) => {
    updateAIMessage(aiMessage, response || '响应超时，请重试');
    completeRequest();
  };

  // 处理成功接收响应
  const handleSuccessResponse = (response, aiMessage) => {
    if (!response) {
      updateAIMessage(aiMessage, '未收到有效响应，请重试');
      completeRequest();
      return;
    }
    completeRequest();
  };

  // 只有当没有memoryId时，才需要获取新的memoryId
  if (!flg.value || !memoryId.value) {
    const res = await getMemoryId();

    if (res.code === 0) {
      memoryId.value = res.data;
      message.memoryId = res.data;
      localStorage.setItem('memoryId', memoryId.value);
      localStorage.setItem('flg', 'true');
      flg.value = true;
    } else {
      console.error('获取memoryId失败:', res);
    }
  }

  // 使用封装的API发送请求
  await streamChat(
      message,
      // 数据块处理 - 实时更新AI消息
      (chunk) => {
        if (chunk) {
          fullResponse += chunk;
          // 实时更新AI消息内容
          updateAIMessage(aiMessage, fullResponse);
        }
      },
      // 错误处理
      (error) => {
        console.error('请求出错:', error);
        handleRequestError(fullResponse, aiMessage);
        completeRequest();
      },
      // 完成回调
      () => handleSuccessResponse(fullResponse, aiMessage),
      abortController.value.signal
  );
};

/**
 * 更新AI消息内容
 * @param {Object} message - AI消息对象
 * @param {string} content - 新的消息内容
 */
const updateAIMessage = (message, content) => {
  if (!message || content === undefined) return;

  // 更新消息内容
  message.content = content;

  // 触发视图更新
  messages.value = [...messages.value];

  // 滚动到底部
  scrollToBottom();
};

/**
 * 重置当前聊天，准备新对话
 */
const resetChat = async () => {
  try {
    loading.value = true;

    // 重置当前聊天界面，不调用删除API
    messages.value = [];
    memoryId.value = '';
    message.value.memoryId = '';
    localStorage.removeItem('memoryId');
    localStorage.removeItem('flg');
    flg.value = false;

  } catch (error) {
    console.error('重置聊天失败:', error);
  } finally {
    loading.value = false;
  }
};

/**
 * 加载特定对话的聊天消息
 * @param {string} chatId - 要加载的聊天ID
 */
const loadChatMessages = async (chatId) => {
  try {
    loading.value = true;
    const result = await getMessages(chatId);
    console.log('获取特定对话消息结果:', result);

    if (result && result.code === 0 && Array.isArray(result.data)) {
      // 将后端返回的消息格式转换为前端使用的格式
      const formattedMessages = result.data.map(msg => ({
        id: msg.id || `msg_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`,
        content: msg.content,
        role: msg.role === 'assistant' ? 'ai' : msg.role,
        createdAt: msg.createdAt || new Date()
      }));

      // 确保消息按照创建时间排序
      formattedMessages.sort((a, b) => {
        return new Date(a.createdAt) - new Date(b.createdAt);
      });

      messages.value = formattedMessages;

      // 更新当前对话的memoryId
      memoryId.value = chatId;
      message.value.memoryId = chatId;
      localStorage.setItem('memoryId', chatId);
      localStorage.setItem('flg', 'true');
      flg.value = true;
    }
  } catch (error) {
    console.error('加载特定对话消息失败:', error);
  } finally {
    loading.value = false;
    // 滚动到底部
    setTimeout(scrollToBottom, CONFIG.SCROLL_DELAY);
  }
};

/**
 * 从后端获取消息
 */
const fetchMessagesFromBackend = async () => {
  if (memoryId.value) {
    // 如果有memoryId，则加载对应的聊天记录
    await loadChatMessages(memoryId.value);
  } else {
    // 否则清空消息列表，准备新对话
    messages.value = [];
  }
};

/**
 * 滚动消息容器到底部
 * 只在用户发送消息或页面初始化时自动滚动，AI回复时不强制滚动
 * @param {boolean} force - 是否强制滚动（即使在AI响应过程中）
 */
const scrollToBottom = (force = false) => {
  // 如果正在加载AI消息且不是强制滚动，则不执行滚动操作
  if (loading.value && !force) {
    return;
  }

  const container = document.querySelector('.messages-container');
  if (container) {
    setTimeout(() => {
      container.scrollTop = container.scrollHeight;
    }, CONFIG.SCROLL_DELAY);
  }
};

// 监听消息变化，仅在新增用户消息时自动滚动
watch(messages, (newMessages, oldMessages) => {
  // 仅当新增消息，且最新消息是用户消息时自动滚动
  if (newMessages.length > oldMessages.length) {
    const lastMsg = newMessages[newMessages.length - 1];
    if (lastMsg && lastMsg.role === 'user') {
      scrollToBottom(true); // 用户发消息时强制滚动
    }
  }
}, {deep: true});

// 页面加载时初始化
onMounted(() => {
  // 从后端获取消息并确保正确排序
  fetchMessagesFromBackend();

  // 确保所有消息都显示在视图中
  setTimeout(scrollToBottom, CONFIG.SCROLL_DELAY);
});

/**
 * 处理请求错误
 * @param {string} fallbackResponse - 可选的已收集的响应
 * @param {Object} message - AI消息对象
 */
const handleRequestError = (fallbackResponse, message) => {
  const errorMessage = fallbackResponse || '请求出错，请稍后再试';
  updateAIMessage(message, errorMessage);
  loading.value = false;
};
</script>

<template>
  <div class="chat-view">
    <div class="messages-container">
      <!-- 消息列表 -->
      <div v-for="message in messages" :key="message.id"
           :class="['message', message.role === 'user' ? 'user-message' : 'ai-message']">
        <div class="message-content">
          <div class="message-header">{{ message.role === 'user' ? '你' : 'AI' }}</div>
          <!-- 用户消息使用普通文本显示 -->
          <div v-if="message.role === 'user'" class="message-body">{{ message.content }}</div>
          <!-- AI消息使用格式化组件显示 -->
          <AiMessage v-else :content="message.content" class="ai-message-body"/>
        </div>
      </div>
    </div>

    <!-- 输入区域 -->
    <div class="input-area">
      <div class="input-container">
        <textarea v-model="prompt" @keydown.enter.shift.exact.prevent @keydown.enter.exact.prevent="sendMessage"
                  placeholder="输入你的问题" :disabled="loading">
        </textarea>
        <button class="send-btn" @click="sendMessage" :disabled="loading || !prompt.trim()">
          <font-awesome-icon :icon="loading ? ['fas', 'spinner'] : ['fas', 'paper-plane']" :spin="loading"/>
        </button>
      </div>
      <div class="input-tools">
        <button class="tool-btn" title="上传图片">
          <font-awesome-icon :icon="['fas', 'image']"/>
        </button>
        <button class="tool-btn" title="表情">
          <font-awesome-icon :icon="['fas', 'face-smile']"/>
        </button>
        <button class="tool-btn" title="语音输入">
          <font-awesome-icon :icon="['fas', 'microphone']"/>
        </button>
      </div>
    </div>
  </div>
</template>

<style scoped>
.chat-view {
  display: flex;
  flex-direction: column;
  height: 100%;
  width: 100%;
}

.messages-container {
  flex: 1;
  overflow-y: auto;
  padding: 0px 20px;
  background-color: transparent;
}

/* 消息和AI消息样式 */
.message {
  margin-bottom: 15px;
  display: flex;
  width: 100%;
  clear: both;
}

.message-content {
  padding: 12px 15px;
  border-radius: 15px;
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);
  position: relative;
}

.user-message .message-content {
  background-color: #007bff;
  color: white;
  margin-left: auto;
  border-bottom-right-radius: 5px;
  max-width: 80%;
}

.ai-message .message-content {
  background-color: #f0f0f0;
  color: #333;
  margin-right: auto;
  border-bottom-left-radius: 5px;
  max-width: 80%;
}

.message-header {
  font-weight: bold;
  margin-bottom: 8px;
  font-size: 0.85rem;
}

.user-message .message-header {
  color: rgba(255, 255, 255, 0.9);
}

.ai-message .message-header {
  color: #555;
}

.message-body {
  white-space: pre-wrap;
  word-break: break-word;
  line-height: 1.4;
}

.ai-message-body {
  text-align: left;
  width: 100%;
  overflow-x: auto;
}

/* 输入区域 */
.input-area {
  padding: 15px 20px;
  border-top: 1px solid #e0e0e0;
  background-color: #fff;
}

.input-container {
  display: flex;
  align-items: flex-end;
  margin-bottom: 8px;
}

textarea {
  flex: 1;
  padding: 12px 15px;
  border: 1px solid #ddd;
  border-radius: 20px;
  resize: none;
  height: 40px;
  max-height: 120px;
  margin-right: 10px;
  font-family: inherit;
  line-height: 1.5;
  font-size: 14px;
}

textarea:focus {
  outline: none;
}

.send-btn {
  width: 40px;
  height: 40px;
  border-radius: 50%;
  background-color: #007bff;
  color: white;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: background-color 0.2s;
}

.send-btn:hover {
  background-color: #0069d9;
}

.send-btn:disabled {
  background-color: #ccc;
}

.input-tools {
  display: flex;
  align-items: center;
  padding-left: 10px;
}

.tool-btn {
  background: none;
  border: none;
  color: #666;
  width: 32px;
  height: 32px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  margin-right: 8px;
  transition: background-color 0.2s;
}

.tool-btn:hover {
  background-color: #f0f0f0;
  color: #333;
}

.tip {
  margin-left: auto;
  font-size: 12px;
  color: #999;
}

/* 代码块样式 */
.ai-message .message-content :deep(pre) {
  max-width: 100%;
  overflow-x: auto;
  background-color: #f5f5f5;
  color: #333;
  padding: 12px;
  border-radius: 6px;
  border: 1px solid #e0e0e0;
}
</style>
